
#include "logger.h"
#include <sstream>
#include <log4cxx/logger.h>
#include <log4cxx/basicconfigurator.h>
#include <log4cxx/xml/domconfigurator.h>
#include <log4cxx/helpers/exception.h>

namespace night_sky
{
  // static

  void Logger::setup(const std::string& conf_path, const std::string& category)
  {
    Logger& logger = Logger::getInstance();
    logger.initialize(conf_path, category);
  }

  Logger& Logger::getInstance()
  {
    static Logger logger;
    return logger;
  }

  // instance

  struct Impl
  {
    log4cxx::LoggerPtr ptr;
  };

  Logger::Logger()
    : m_pimpl(new Impl())
  {}

  Logger::~Logger()
  {
    destroy();
  }

  void Logger::initialize(const std::string& conf_path, const std::string& category)
  {
    this->m_pimpl->ptr = log4cxx::Logger::getLogger(category);
    try
    {
      log4cxx::xml::DOMConfigurator::configure(conf_path);
    }
    catch(const log4cxx::helpers::Exception& e)
    {
      log4cxx::BasicConfigurator::configure();
    }
  }

  void Logger::destroy()
  {
    if (this->m_pimpl != NULL)
    {
      delete this->m_pimpl;
      this->m_pimpl = NULL;
    }
  }

  void Logger::debug(const std::string& msg)
  {
    LOG4CXX_DEBUG(this->m_pimpl->ptr, msg);
  }

  void Logger::info(const std::string& msg)
  {
    LOG4CXX_INFO(this->m_pimpl->ptr, msg);
  }

  void Logger::warn(const std::string& msg)
  {
    LOG4CXX_WARN(this->m_pimpl->ptr, msg);
  }

  void Logger::error(const std::string& msg)
  {
    LOG4CXX_ERROR(this->m_pimpl->ptr, msg);
  }

  void Logger::fatal(const std::string& msg)
  {
    LOG4CXX_FATAL(this->m_pimpl->ptr, msg);
  }

  bool Logger::isInfoEnabled() const
  {
    return this->m_pimpl->ptr->isInfoEnabled();
  }

  bool Logger::isWarnEnabled() const
  {
    return this->m_pimpl->ptr->isWarnEnabled();
  }

  bool Logger::isErrorEnabled() const
  {
    return this->m_pimpl->ptr->isErrorEnabled();
  }
}

